#ifndef COMMON_DEFS_H
#define COMMON_DEFS_H

#ifdef __cplusplus
extern "C" {
#endif

#define HASH_SIZE 128           // 每个作用域的符号表大小
#define MAX_SCOPE 32            // 最大作用域嵌套深度

#include <stdint.h>

// tokens和类别定义 (运算符按优先级顺序排列)
typedef enum {
  Num = 128, Str,Fun, Sys, Glo, Loc, Para, Block, Id,
  Char, Else, Enum, If, Int, Return, Sizeof, While, For,
  Assign, Cond, Lor, Lan, Or, Xor, And, Eq, Ne, Lt, Gt, Le, Ge, Shl, Shr, Add, Sub, Mul, Div, Mod, Inc, Dec, Brak
} TokenType;

// 符号表字段定义
enum {Token, Hash, Name, Type, Class, Value, Dvalue, BType, BClass, BValue, IdSize}; // Name是该标识符在src中的起始位置

// 虚拟机指令集定义
enum { LEA, IMM, JMP, CALL, JZ, JNZ, JFZ, ENT, ADJ, LEV, LI, LC, SI, SC, PUSH,
       OR, XOR, AND, EQ, NE, LT, GT, LE, GE, SHL, SHR, ADD, SUB, MUL, DIV, MOD,
       OPEN, READ, CLOS, PRTF, MALC, MSET, MCMP, SCANF, FREE, EXIT };

// 变量/函数返回类型
enum { CHAR, INT, PTR };

typedef enum {  // Class，符号表类型
    SYM_GLOBAL,    // 全局变量
    SYM_LOCAL,     // 局部变量
    SYM_ENUM,      // 枚举变量
    SYM_FUNCTION,  // 函数
    SYM_PARAM,     // 函数参数
    SYM_SYSTEM,     // 系统函数
    SYM_BLOCK       // 代码块
} SymClass;

typedef enum {  // Type，返回值类型和变量类型
    TYPE_INT,
    TYPE_CHAR,
    TYPE_VOID,
    TYPE_PTR_INT,
    TYPE_PTR_CHAR,
} DataType;

// 参数信息结构
typedef struct Param {
    DataType type;      // 参数类型
    const char* name;   // 参数名称
    intptr_t offset;    // 参数偏移量
    struct Param* next; // 链表下一个参数
} Param;

typedef union {
    intptr_t long_val;  // 用于存储char，int类型
    char* string_val;   // 用于存储字符串
} DValue;

// 前向声明
struct Scope;
struct SymInfo;
struct Symbol;

// 符号信息结构
typedef struct SymInfo {
    SymClass sym_class;   // 符号类别
    DataType data_type;   // 数据类型和返回值类型
    const char* name;     // 符号名称
    intptr_t addr;        // 地址/偏移
    
    // 动态值存储（支持int/char及其指针），比如在初始化时临时存储右值。当变量被赋值时，更新动态存储的值。
    union {
        intptr_t int_val;  // 用于存储int和char型
        intptr_t ptr_val;  // 存储指针指向的地址，包括字符串的地址
    } dvalue;

    struct Scope* scope;   // 所属作用域
    int64_t is_pointer;    // 是否为指针类型（>=1是）, 0不是。1是1级指针，2是2级指针，以此类推
    int64_t is_init;    // 是否已需要初始化
    
    // 函数特有字段
    Param* params;         // 参数链表
    int64_t param_count;   // 参数数量
    struct Scope* func_scope;  // 函数体作用域
} SymInfo;

// 哈希表
typedef struct Symbol {
    const char* name;     // 符号名
    SymInfo* info;        // 符号信息
    struct Symbol* next;  // 哈希冲突链表
} Symbol;

// 作用域结构
typedef struct Scope {
    Symbol* hash_table[HASH_SIZE]; // 哈希表，表头
    int level;                     // 作用域层级
    struct Scope* parent;          // 父作用域
} Scope;

// 全局作用域栈
typedef struct {
    Scope* stack[MAX_SCOPE];  // 作用域栈
    int top;                  // 栈顶指针
} ScopeStack;

// 全局变量声明 - 符号表相关
extern ScopeStack* scope_stack;     // 全局作用域栈

// 全局变量声明 - 词法分析器相关
extern int token;                    // 当前token
extern int token_val;                // 当前token的值（主要用于数字）
extern char *src, *old_src;          // 源代码指针
extern int line;                     // 行号
extern int column;                   // 列号
extern intptr_t *current_id;         // 当前解析的ID
extern intptr_t *symbols;            // 符号表
extern intptr_t *idmain;             // 保存main函数ID位置
extern char token_buffer[2048];      // 词法分析器的token缓冲区

// 全局变量声明 - 虚拟机相关
extern int poolsize;                 // 默认内存池大小
extern intptr_t *text;               // 代码段
extern char *data;                   // 数据段
extern char *data_start;
extern intptr_t *stack;              // 栈
extern intptr_t *pc, *bp, *sp;       // 程序计数器、基址指针、栈指针
extern intptr_t ax, cycle;           // 累加器、周期计数器
extern intptr_t *text_start, *stack_start, *symbols_start;

// 解析器相关
extern int basetype;                 // 声明的类型
extern int expr_type;                // 表达式的类型
extern int index_of_bp;              // 栈中bp指针的索引
extern int vm_argc;
extern char **vm_argv;

// 词法分析器函数 - 在其他文件中被调用
void next();
void match(int tk);

// 编译器初始化函数
void init_compiler_memory(int pool_size, const char* code);

// 符号表操作函数声明
// 当前处理的函数名
extern char* current_func_name;
extern ScopeStack* scope_stack;

// 哈希函数声明
unsigned int hash_string(const char* str);

Scope* create_scope(Scope* parent);
void push_scope(ScopeStack* stack);
void pop_scope(ScopeStack* stack);
Symbol* add_symbol(Scope* scope, const char* name, SymInfo* info);
SymInfo* create_symbol_info(const char* name, int old_type, int old_class, intptr_t addr);
Symbol* find_symbol_current(Scope* scope, const char* name);
Symbol* find_symbol_all(ScopeStack* stack, const char* name);
Scope* current_scope(ScopeStack* stack);
void free_scope(Scope* scope);
void free_scope_stack(ScopeStack* stack);

// 符号表遍历相关函数声明
void traverse_symbol_table(Scope* scope); // 向下遍历当前符号表
void print_symbol_total(Scope* scope);
void print_scope_header(Scope* scope);
void print_symbol_info(Symbol* symbol);
void print_symbol_details(SymInfo* info);
void print_function_params(Param* params);
void print_initialization_info(SymInfo* info);
const char* get_symbol_class_name(SymClass class);
const char* get_data_type_name(DataType type);
char* get_symbol_result_string(Scope* scope); // 获取符号表的格式化字符串接口

#ifdef __cplusplus
}
#endif

#endif /* COMMON_DEFS_H */ 